package com.taysear.parcel.util;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Random;

import com.vaadin.ui.Button;
import com.vaadin.ui.Window;
import com.vaadin.ui.Button.ClickEvent;

/**
 * All the common logic of the application will came here.
 * 
 * @author Abdullahi
 * 
 */
public class Util {

	/**
	 * Gets the Integer value of a String
	 * 
	 * @param value
	 * @return Integer
	 */
	public static Integer getIntegerValue(String value) {
		Integer vNumber = null;
		try {
			vNumber = Integer.parseInt(value); 
		} catch (NumberFormatException e) { }
		return vNumber;
	}
	
	/**
	 * Gets the BigDecimal value of a String
	 * 
	 * @param value
	 * @return BigDecimal
	 */
	public static BigDecimal getBigDecimalValue(String value) {
		BigDecimal number = null;
		try {
			number = new BigDecimal(value); 
		} catch (NumberFormatException e) { }
		return number;
	}
	
	/**
	 * Gets the start of a day, example: 12/01/2012 00:00
	 * 
	 * @param date
	 * @return Date
	 */
	public static Date getStartOfADay(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.MILLISECOND, 0);
		return new Date(cal.getTimeInMillis());
	}
	
	/**
	 * Gets the end of a day, example: 12/01/2012 23:59
	 * 
	 * @param date
	 * @return Date
	 */
	public static Date getEndOfADay(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.set(Calendar.HOUR_OF_DAY, 23);
		cal.set(Calendar.MINUTE, 59);
		cal.set(Calendar.SECOND, 59);
		return new Date(cal.getTimeInMillis());
	}
	
	/**
	 * Set the hour and minutes of a date.
	 * 
	 * @param date
	 * @param hour
	 * @param minute
	 * @param isPm
	 * 
	 * @return Date
	 */
	public static Date setDateHourAndMinute(Date date, int hour, int minute, Boolean isPm) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.set(Calendar.HOUR_OF_DAY, isPm ? hour + 12 : hour);
		cal.set(Calendar.MINUTE,  minute);
		cal.set(Calendar.SECOND, 00);
		return new Date(cal.getTimeInMillis());
	}
	
	/**
	 * Gets a date that x months plus the date that is passed.
	 * 
	 * @param date
	 * @param monthsToAdd
	 * @return Date
	 */
	public static Date addMonthsToDate(Date date, Integer monthsToAdd) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.add(Calendar.MONTH, monthsToAdd);
		return new Date(cal.getTimeInMillis());
	}
	
	/**
	 * Gets a date that x months minus the date that is passed.
	 * 
	 * @param date
	 * @param monthsToSubtract
	 * @return Date
	 */
	public static Date subtractMonthsFromDate(Date date, Integer monthsToSubtract) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.add(Calendar.MONTH, - monthsToSubtract);
		return new Date(cal.getTimeInMillis());
	}
	
	/**
	 * Gets date from date string.
	 * 
	 * @param dateString yyyy-MM-dd HH:mm:ss
	 * 
	 * @return Date
	 */
	public static Date getDate(String dateString){
    	Date result = null;
		try {
			DateFormat formatter = new SimpleDateFormat(Constants.DATE_FORMAT_STRING_DB);
			result = (Date) formatter.parse(dateString);

		} catch (ParseException e) {
			System.out.println("Unparseable date: " +dateString);
		}
		return result;
    }
	
	/**
	 * Gets a formatted date string without the time portion.
	 * 
	 * @param dateString yyyy-MM-dd
	 * @return String  dd/MM/yyyy
	 */
	public static String formatDateWithoutTime(String dateString){
    	String result = null;
		try {
			DateFormat formatter = new SimpleDateFormat(Constants.DATE_FORMAT_STRING_DB_SHORT);
			Date date = (Date) formatter.parse(dateString);
			
			SimpleDateFormat sdf = new SimpleDateFormat(Constants.DATE_FORMAT_STRING);  
			result = sdf.format(date);
		} catch (ParseException e) {
			System.out.println("Unparseable date: " +dateString);
		}
		return result;
    }
	
	/**
	 * Gets a formatted date string without the time portion.
	 * 
	 * @param date  
	 * @return String dd/MM/yyyy
	 */
	public static String formatDateWithoutTime(Date date){
    	SimpleDateFormat sdf = new SimpleDateFormat(Constants.DATE_FORMAT_STRING);  
    	String result = null;
		result = sdf.format(date);
		return result;
    }
	
	/**
	 * Gets a formatted date string.
	 * 
	 * @param dateString yyyy-MM-dd HH:mm:ss
	 * 
	 * @return String dd/MM/yyyy HH:mm
	 */
	public static String formatDate(String dateString){
    	String result = null;
		try {
			DateFormat formatter = new SimpleDateFormat(Constants.DATE_FORMAT_STRING_DB);
			Date date = (Date) formatter.parse(dateString);
			
			SimpleDateFormat sdf = new SimpleDateFormat(Constants.DATE_FORMAT_STRING_LONG);  
			result = sdf.format(date);
		} catch (ParseException e) {
			System.out.println("Unparseable date: " +dateString);
		}
		return result;
    }
	
	/**
	 * Gets a formatted date string.
	 * 
	 * @param date
	 * @return String dd/MM/yyyy HH:mm
	 */
	public static String formatDate(Date date){
    	String result = null;
		SimpleDateFormat sdf = new SimpleDateFormat(Constants.DATE_FORMAT_STRING_LONG);  
		result = sdf.format(date);
		return result;
    }
	
	/**
	 * Gets a formatted date string.
	 * 
	 * @param date
	 * @return String yyyy-MM-dd HH:mm:ss
	 */
	public static String formatDateForDB(Date date){
    	String result = null;
		SimpleDateFormat sdf = new SimpleDateFormat(Constants.DATE_FORMAT_STRING_DB);  
		result = sdf.format(date);
		return result;
    }
	
	/**
	 * Generates Key of a specified length
	 * 
	 * @param length
	 * @return String
	 */
	public static String generateKey(int length) {
		Random rand = new Random();
		int min = getLDV(length);
		int max = getLDV(length + 1) - 1;
		int randomNum = rand.nextInt((max - min) + 1) + min;

		return Integer.toString(randomNum);
	}

	/**
	 * Gets LowestValue in given digit range
	 * 
	 * @param n
	 * @return int
	 */
	public static int getLDV(int n) {
		String str = "1";
		for (int i = 1; i <= (n - 1); str += "0", i++);

		return Integer.parseInt(str);
	}
	
	/**
	 * Gets a string that is the format money value example 123,456.78
	 * 
	 * @param money
	 * 
	 * @return String
	 */
	public static String formatMoney(String value) {
		BigDecimal modelVal = new BigDecimal(value);
		BigDecimal displayVal = modelVal.setScale(2, RoundingMode.HALF_EVEN);
		
		DecimalFormat formatter = new DecimalFormat("###,###.##");
		formatter.setMinimumFractionDigits(2);
		formatter.setMaximumFractionDigits(2);
		return formatter.format(displayVal);
	}
	
	/**
	 * Gets a button to close the window that is passed as a parameter.
	 * 
	 * @param window
	 * @return Button
	 */
	public static Button getCloseButton(final Window window) {
		Button button = new Button("Close");
		button.addStyleName("grayButton");
		button.addListener(new Button.ClickListener() {
			public void buttonClick(ClickEvent event) {
				window.getParent().removeWindow(window);
			}
    	});
    	return button;
	}
	
	/**
	 * Checks if the value of string is empty or not.
	 * 
	 * @param value
	 * 
	 * @return Boolean
	 */
	public static Boolean isNotEmptyResult(String value) {
		Boolean result = false;
		if(value != null && !"null".equalsIgnoreCase(value) && !"".equalsIgnoreCase(value))
			result = true;
		
		return result;
	}
}
